package ac.il.technion.cs236635.project.core;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.log4j.Logger;

import ac.il.technion.cs236635.project.core.dispatcher.Dispatcher;
import ac.il.technion.cs236635.project.core.dispatcher.DispatcherService;
import ac.il.technion.cs236635.project.core.dispatcher.ServerInfo;
import ac.il.technion.cs236635.project.core.server.CloudWorkerService;
import ac.il.technion.cs236635.project.core.server.ServerJob;

public class JobsSender implements Runnable {

	private volatile boolean finished = false;
	
	private String dispatchEndpoint = ""; 
	
	private QName dispatchQName	= new QName("http://core.project.cs236635.technion.il.ac/", "DispatcherService");
	
	private QName serverQName 	= new QName("http://core.project.cs236635.technion.il.ac/", "CloudWorkerService");
	
	private Logger log = Logger.getLogger( JobsSender.class);
	
	public JobsSender( ) {
		Properties properties = new Properties( );
		try {
			properties.load( JobsSender.class.getClassLoader( ).getResourceAsStream( "client.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.dispatchEndpoint = properties.getProperty( "dispacherURL");
	}
	
	@Override
	public void run() {
		while( !finished) {
			ServerJob nextJob = JobsSubmitted.getInstance().getNextJob( );
			if ( nextJob == null) {
				try {
					Thread.sleep( 50); // Make it highly responsive
					continue;
				} catch (InterruptedException e) {
					log.error( e);
				}
			}
			try {
				DispatcherService service = new DispatcherService( new URL( dispatchEndpoint), dispatchQName);
				Dispatcher dispatcher = service.getDispatcherPort( );
				// Need to pick two servers from the list to send the job
				ServerInfo highPrioInfo = dispatcher.acquire( ); // Randomly pick the first one
				ServerInfo lowPrioInfo = dispatcher.acquire( );
				while ( lowPrioInfo.getServerName( ).equals(highPrioInfo.getServerName( ))) {
					lowPrioInfo = dispatcher.acquire( ); // Ensure the second one is completely different
				}
				JobsKeeper.getInstance().insertJob( nextJob);
				CloudWorkerService highPrioService = new CloudWorkerService( new URL( highPrioInfo.getServerEnpoint( )), serverQName);
				log.info( "Job with id: " + nextJob.getJobId( ) + " submitted to " + highPrioInfo.getServerName( ) + " high queue");
				CloudWorkerService lowPrioService = new CloudWorkerService( new URL( lowPrioInfo.getServerEnpoint( )), serverQName);
				log.info( "Job with id: " + nextJob.getJobId( ) + " submitted to " + lowPrioInfo.getServerName( ) + " low queue");
				highPrioService.getCloudWorkerPort( ).submitHighJob( nextJob);
				lowPrioService.getCloudWorkerPort( ).submitLowJob( nextJob);
			} catch (MalformedURLException e) {
				log.error( e);
			}
		}
	}

	public void finish( ) {
		finished = true;
	}
}